package com.asman.vr.answer

import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.DialogInterface
import android.media.Image
import android.media.MediaPlayer
import android.net.Uri
import android.os.Handler
import android.os.Vibrator
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.animation.LinearInterpolator
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.lifecycle.*
import com.asman.base.lib.glide.GlideApp
import com.asman.base.lib.utils.StatusBarUtil
import com.asman.vr.DialogLoadingFragment
import com.asman.vr.R
import com.asman.vr.constant.UrlConst
import com.asman.vr.dto.SchemeInfoDetailData
import com.asman.vr.network.*
import com.asman.vr.utils.DialogUtils
import com.asman.vr.utils.EventData
import com.asman.vr.utils.StringAppendUtils
import io.flutter.plugin.common.MethodChannel
import log
import org.greenrobot.eventbus.Subscribe
import ossZip
import showToast
import java.io.IOException
import fen2Yuan

class AnswerView : RelativeLayout {

    // var activity: Activity? = null
    var methodChannel: MethodChannel? = null

    var checkRoomCallback: CheckRoomCallbackInterface? = null
    var checkRoomCallback3Seconds: CheckRoomCallback3SecondsInterface? = null
    var checkRoomCallbackAccept: CheckRoomCallbackAcceptInterface? = null

    // 业务参数
    var schemeId: Int? = null//方案id
    var roomId: Int? = null//邀请加入的房间
    var headUrl: String? = null//来电人的头像
    var name: String? = null//来电人的名字
    var userId: String? = null//来电人的userId
    var accountId: Long? = null//来电人的accountId
    var vrType: Int? = null
    var groupId: String? = null
    var schemeInfoDetail: SchemeInfoDetailData? = null

    constructor(
            context: Context, methodChannel: MethodChannel,
            schemeId: Int?, roomId: Int?, headUrl: String?, name: String?,
            userId: String?, accountId: Long?, vrType: Int?, groupId: String?,
            schemeInfoDetail: SchemeInfoDetailData?
    ) : this(
            context, methodChannel,
            schemeId, roomId, headUrl, name,
            userId, accountId, vrType, groupId,
            schemeInfoDetail,
            null, 0
    )
    
    constructor(
            context: Context, methodChannel: MethodChannel,
            schemeId: Int?, roomId: Int?, headUrl: String?, name: String?,
            userId: String?, accountId: Long?, vrType: Int?, groupId: String?,
            schemeInfoDetail: SchemeInfoDetailData?,
            attrs: AttributeSet
    ) : this(
            context, methodChannel,
            schemeId, roomId, headUrl, name,
            userId, accountId, vrType, groupId,
            schemeInfoDetail,
            attrs, 0
    )
    
    constructor(
            context: Context, methodChannel: MethodChannel,
            schemeId: Int?, roomId: Int?, headUrl: String?, name: String?,
            userId: String?, accountId: Long?, vrType: Int?, groupId: String?,
            schemeInfoDetail: SchemeInfoDetailData?,
            attrs: AttributeSet?, defStyleAttr: Int
    ) : super(context, attrs, defStyleAttr) {
        // this.activity = activity
        this.methodChannel = methodChannel
        
        // 业务参数
        this.schemeId = schemeId;
        this.roomId = roomId;
        this.headUrl = headUrl;
        this.name = name;
        this.userId = userId;
        this.accountId = accountId;
        this.vrType = vrType;
        this.groupId = groupId;
        
        this.schemeInfoDetail = schemeInfoDetail;

        LayoutInflater.from(context).inflate(R.layout.activity_call_answer, this, true)


        // todo onCreate 中的内容，转移到构造函数中 - done
        /*RouterUtils.inject(this)
        userId = intent?.extras?.getLong("userId")
        if (intent?.extras?.containsKey("accountId") == true) {
            accountId = intent?.extras?.getLong("accountId")
        }
        roomId = intent?.extras?.getInt("roomId")
        headUrl = intent?.extras?.getString("headUrl")
        name = intent?.extras?.getString("name")
        schemeId = intent?.extras?.getLong("schemeId")
        vrType = intent?.extras?.getInt("vrType")
        groupId = intent?.extras?.getString("groupId")*/

        log("userId=$userId,roomId=$roomId,headUrl=$headUrl,name=$name,schemeId=$schemeId，groupId=${groupId}")
        // StatusBarUtil.setTranslucent(activity)
        // StatusBarUtil.setLightMode(activity)

        // todo model 不能这么初始化，废弃 viewmodal-done
        /*model = ViewModelProviders.of(activity, object : ViewModelProvider.Factory {
            override fun <T : ViewModel?> create(modelClass: Class<T>): T {
                val repo = ServiceLocator.instance(context).getSchemeRepository()
                val repo1 = ServiceLocator.instance(context).getCallAnswerRepository()
                return CallAnswerViewModel(repo, repo1) as T
            }
        })[CallAnswerViewModel::class.java]*/

        getSchemeInfo()
        initClick()
        //查询通话是否还有效
        _首次校验()
        
    }

    // todo 跳转页面，用 flutter 传进来的方法
    /*companion object {
        fun startActivity(context: Context) {
            val intent = Intent(context, CallAnswerActivity::class.java)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
            context.startActivity(intent)
        }
    }*/

    val time = 600L

    var model: CallAnswerViewModel? = null

    // todo - 拿掉钩子，直接放到构造函数 - done
    /*override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_call_answer)
        EventBusUtils.register(this)

        RouterUtils.inject(this)
        userId = intent?.extras?.getLong("userId")
        if (intent?.extras?.containsKey("accountId") == true) {
            accountId = intent?.extras?.getLong("accountId")
        }
        roomId = intent?.extras?.getInt("roomId")
        headUrl = intent?.extras?.getString("headUrl")
        name = intent?.extras?.getString("name")
        schemeId = intent?.extras?.getLong("schemeId")
        vrType = intent?.extras?.getInt("vrType")
        groupId = intent?.extras?.getString("groupId")

        log("userId=$userId,roomId=$roomId,headUrl=$headUrl,name=$name,schemeId=$schemeId，groupId=${groupId}")
        StatusBarUtil.setTranslucent(this)
        StatusBarUtil.setLightMode(this)
        model = ViewModelProviders.of(this, object : ViewModelProvider.Factory {
            override fun <T : ViewModel?> create(modelClass: Class<T>): T {
                val repo = ServiceLocator.instance(this@CallAnswerActivity).getSchemeRepository()
                val repo1 =
                        ServiceLocator.instance(this@CallAnswerActivity).getCallAnswerRepository()
                return CallAnswerViewModel(repo, repo1) as T
            }
        })[CallAnswerViewModel::class.java]

        getSchemeInfo()
        initClick()
        //查询通话是否还有效
        _首次校验()
    }*/

    private fun router3DRoam() {
        // todo 友盟 事件埋点
        /*UmengUtils.onEventObject(
                this, UMEventKey.voice_listen.rendering_id.id,
                mapOf(
                        UMEventKey.voice_listen.rendering_id.key to schemeId,
                        UMEventKey.voice_listen.user_id.key to sp.getLong(SP_USER_ID, 0)
                )
        )*/
        // todo 跳转到 vr 页面，并结束接听页面；在 flutter 层面 replace 到 vr 页面 - done
        methodChannel!!.invokeMethod("router3DRoam", "")
        destroy()
        /*val url = UrlConst.getFull3DRoamUrl(
                schemeId = schemeId,
                vrType = vrType,
                token = sp.getString(SP_LOGIN_TOKEN, null),
                roomId = roomId,
                groupId = groupId
                tenant = sp.getString(SP_CHOICE_COMPANY_Domain_Prefix, null)
        )
        RouterUtils.get(RouterUrl.VRWebActivity)
                .withString("url", url)
                .withBoolean("hiddenTitle", true)
                .withBoolean("fullScreen", true)
                .withBoolean("isFromReceive", true)
                .navigation()
        activity?.finish()*/
    }

    private fun getSchemeInfo() {

        // todo 接口放到 flutter 去调
        /*// 调接口提交日志
        model?.submitTrtcLog(roomId, userId)?.observe(context as LifecycleOwner, Observer {
        })*/

        // todo 脱离 model，schemeInfoDetail 在 flutter 层面请求好，直接传进来 - done
        this.schemeInfoDetail?.let { initCardView(it) }
        /*model?.getSchemeInfoDetail(schemeId ?: 0, vrType)?.observe(context as LifecycleOwner, Observer {
            when (it.status) {
                Status.LOADING -> {
                }
                Status.SUCCESS -> {
                    model?.data = it.data!!
                    initCardView(it.data!!)
                }
            }
        })*/
    }

    //当前通话是否还有效，做校验
    private fun _首次校验() {
        showDialogProgress("校验信息...")
        // todo-通过 flutter 层调接口 -done
        checkRoomCallback = object : CheckRoomCallbackInterface {
            override fun validCallbackNameFirst() {
                dismissDialog()
                startCall()
                //轮训校验是否有效
                Handler().postDelayed({
                    _3秒轮训校验()
                }, 3000)
            }
            override fun invalidCallbackNameFirst() {
                dismissDialog()
                showTimeOutDialog()
            }
            override fun errorCallbackNameFirst() {
                //轮训校验是否有效
                Handler().postDelayed({
                    _3秒轮训校验()
                }, 3000)
                // todo 异步的结果传不进来
                // showToast(it.message)
                dismissDialog()
            }
        }
        methodChannel!!.invokeMethod("canReceived", "validCallbackNameFirst,invalidCallbackNameFirst,errorCallbackNameFirst")
        /*model?.canReceived(roomId ?: 0)?.observe(context as LifecycleOwner, Observer {
            when (it.status) {
                Status.LOADING -> showDialogProgress("校验信息...")
                Status.SUCCESS -> {
                    //根据接口返回状态，判断是否有效的呼叫
                    dismissDialog()
                    if (it.data == false) {
                        showTimeOutDialog()
                    } else {
                        startCall()
                        //轮训校验是否有效
                        Handler().postDelayed({
                            _3秒轮训校验()
                        }, 3000)
                    }
                }
                else -> {
                    //轮训校验是否有效
                    Handler().postDelayed({
                        _3秒轮训校验()
                    }, 3000)
                    showToast(it.message)
                    dismissDialog()
                }
            }
        })*/
    }

    fun _3秒轮训校验() {
        if (hasShowTimeOutDialog) return
        // todo-通过 flutter 层调接口 -done
        checkRoomCallback3Seconds = object : CheckRoomCallback3SecondsInterface {
            override fun validCallbackName3Seconds() {
                if (hasShowTimeOutDialog) return
                // 轮训校验是否有效
                if (!hasShowTimeOutDialog) {
//                    Handler().postDelayed({
//                        _3秒轮训校验()
//                    }, 3000)
                }
            }
            override fun invalidCallbackName3Seconds() {
                if (hasShowTimeOutDialog) return
                showToast("当前通话已断开")
                methodChannel!!.invokeMethod("onGoBack", "")
            }
            override fun errorCallbackName3Seconds() {
                //轮训校验是否有效
//                Handler().postDelayed({
//                    _3秒轮训校验()
//                }, 3000)
            }

        }
        methodChannel!!.invokeMethod("canReceived", "validCallbackName3Seconds,invalidCallbackName3Seconds,errorCallbackName3Seconds")
        /*model?.canReceived(roomId ?: 0)?.observe(context as LifecycleOwner, Observer {
            when (it.status) {
                Status.LOADING -> {
                }
                Status.SUCCESS -> {
                    if (hasShowTimeOutDialog) return@Observer
                    //根据接口返回状态，判断是否有效的呼叫
                    if (it.data == false) {
                        showToast("当前通话已断开")
                        // todo 不知道能不能直接 finish, 可以直接用 flutter 的 onGoBack
                        activity?.finish()
                    } else {
                        //轮训校验是否有效
                        if (!hasShowTimeOutDialog) {
                            Handler().postDelayed({
                                _3秒轮训校验()
                            }, 3000)
                        }
                    }
                }
                else -> {
                    //轮训校验是否有效
                    Handler().postDelayed({
                        _3秒轮训校验()
                    }, 3000)
                }
            }
        })*/
    }

    private fun _接听() {
        // todo-通过 flutter 层调接口 -done
        // methodChannel!!.invokeMethod("notifyDesignerJoined", "")
        showDialogProgress("校验信息...")
        checkRoomCallbackAccept = object : CheckRoomCallbackAcceptInterface {
            override fun validCallbackNameAccept() {
                dismissDialog()
                router3DRoam()
            }
            override fun invalidCallbackNameAccept() {
                dismissDialog()
//                showTimeOutDialog()
            }
            override fun errorCallbackNameAccept() {
                // todo 异步参数没拿到
                // showToast(it.message)
                dismissDialog()
            }

        }
        methodChannel!!.invokeMethod("answer", "validCallbackNameAccept,invalidCallbackNameAccept,errorCallbackNameAccept")
        /*model?.canReceived(roomId ?: 0)?.observe(context as LifecycleOwner, Observer {
            when (it.status) {
                Status.LOADING -> {
                    showDialogProgress("校验信息...")
                }
                Status.SUCCESS -> {
                    //根据接口返回状态，判断是否有效的呼叫
                    dismissDialog()
                    if (it.data == false) {
                        showTimeOutDialog()
                    } else {
                        router3DRoam()
                    }
                }
                else -> {
                    showToast(it.message)
                    dismissDialog()
                }
            }
        })*/
    }

    //如果超时弹框已经弹出，则轮训停止，其他自动关闭页面的操作也不执行
    var hasShowTimeOutDialog = false

    private fun showTimeOutDialog() {
        hasShowTimeOutDialog = true
        DialogUtils.showDialog(
                context = context,
                title = "当前通话已断开",
                positiveTxt = "确定",
                cancelable = false,
                listener = object : DialogUtils.ButtonClickListener {
                    override fun neutralButton() {
                    }

                    override fun negativeButton() {
                    }

                    override fun positiveButton() {
                        // todo 不知道能不能直接 finish, 可以直接用 flutter 的 onGoBack
                        // activity?.finish()
                    }
                }
        )
    }

    private fun initClick() {
        findViewById<ImageView>(R.id.btn_reject).setOnClickListener {
            // todo 事件埋点
            /*UmengUtils.onEventObject(
                    this, UMEventKey.voice_refuse.rendering_id.id,
                    mapOf(
                            UMEventKey.voice_refuse.rendering_id.key to schemeId,
                            UMEventKey.voice_refuse.user_id.key to sp.getLong(SP_USER_ID, 0)
                    )
            )*/
            
            // todo - 整一块放到 flutter 层面处理 - done
            methodChannel!!.invokeMethod("rejectAnswer", "")
            destroy()
            /*//拒接发送告诉用户正忙
            model?.rejectAnswer(
                    RejectAnswerBody(
                            userId = userId,
                            accountId = if (accountId == 0L) null else accountId,
                            roomId = roomId,
                            schemeId = schemeId,
                            vrType = vrType
                    )
            )?.observe(context as LifecycleOwner, Observer {
                when (it.status) {
                    Status.LOADING -> {
                    }
                    Status.SUCCESS -> {
                        dismissDialog()
                        // todo 不知道能不能直接 finish, 可以直接用 flutter 的 onGoBack
                        activity?.finish()
                    }
                    else -> {
                        dismissDialog()
                        // todo 不知道能不能直接 finish, 可以直接用 flutter 的 onGoBack
                        activity?.finish()
                    }
                }
            })*/
        }

        findViewById<ImageView>(R.id.btn_receive).setOnClickListener {
            _接听()
        }
    }

    //确认没有超时之后 初始化呼叫UI
    private fun startCall() {
        playAnim()
        playSound()
        startZD()
    }

    @SuppressLint("SetTextI18n")
    fun initCardView(data: SchemeInfoDetailData) {
        GlideApp.with(this).load(data.image.ossZip(100f, 70f, 2.0f)).into(findViewById(R.id.iv_scheme))
        findViewById<TextView>(R.id.tv_scheme_name).text = data.buildingName
        val params = StringAppendUtils.stringAppendKeyValue(
                arrayOf(data.buildingArea), arrayOf("㎡"), "", ""
        )

        val houseParams = StringAppendUtils.builder()
                .append(
                        "${data.houseParams?.bedroomNum}室",
                        !(data.houseParams?.bedroomNum == 0 || data.houseParams?.bedroomNum == null)
                )
                .append(
                        "${data.houseParams?.livingRoomNum}厅",
                        !(data.houseParams?.livingRoomNum == 0 || data.houseParams?.livingRoomNum == null)
                )
                .build()

        findViewById<TextView>(R.id.tv_scheme_params).text =
                StringAppendUtils.stringAppend(arrayOf(params, houseParams))
        findViewById<TextView>(R.id.tv_price).text = "¥${data.price.fen2Yuan()}"

        findViewById<TextView>(R.id.tv_user_name).text = name
        GlideApp.with(this)
                .load(headUrl.ossZip(100f, 100f, 2.0f))
                .placeholder(R.drawable.ic_head_default)
                .into(findViewById(R.id.iv_user_head))
    }

    ///////////////动画
    fun playAnim() {
        getHomeLogoAnim(findViewById(R.id.view_0)).start()
        Handler().postDelayed({
            getHomeLogoAnim(findViewById(R.id.view_1)).start()
        }, time * 1)
        Handler().postDelayed({
            getHomeLogoAnim(findViewById(R.id.view_2)).start()
        }, time * 2)
        Handler().postDelayed({
            getHomeLogoAnim(findViewById(R.id.view_3)).start()
        }, time * 3)
        Handler().postDelayed({
            getHomeLogoAnim(findViewById(R.id.view_4)).start()
        }, time * 4)
        Handler().postDelayed({
            getHomeLogoAnim(findViewById(R.id.view_5)).start()
        }, time * 5)
        Handler().postDelayed({
            getHomeLogoAnim(findViewById(R.id.view_6)).start()
        }, time * 6)
    }

    private fun getHomeLogoAnim(view: View): AnimatorSet {
        val scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1.0f, 2.4f)
        scaleX.repeatCount = 1000
        scaleX.repeatMode = ValueAnimator.RESTART
        val scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1.0f, 2.4f)
        scaleY.repeatCount = 1000
        scaleY.repeatMode = ValueAnimator.RESTART
        val alpha = ObjectAnimator.ofFloat(view, "alpha", 0.5f, 0f)
        alpha.repeatCount = 1000
        alpha.repeatMode = ValueAnimator.RESTART
        val set = AnimatorSet()
        set.apply {
            play(scaleX).with(scaleY).with(alpha)
            duration = time * 7
            interpolator = LinearInterpolator()
        }
        return set
    }
    ///////////////动画

    ///////////////铃声
    var mMediaPlayer: MediaPlayer? = null

    fun playSound() {
        mMediaPlayer = MediaPlayer()
        try {
            mMediaPlayer?.setDataSource(
                    context,
                    Uri.parse("android.resource://" + context.packageName + "/" + R.raw.nnd)
                    // Uri.parse("android.resource://" + packageName + "/" + R.raw.nnd)
            )
            mMediaPlayer?.isLooping = true //循环播放
            mMediaPlayer?.prepare()
            mMediaPlayer?.start()
        } catch (e: IllegalArgumentException) {
            e.printStackTrace()
        } catch (e: SecurityException) {
            e.printStackTrace()
        } catch (e: IllegalStateException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    fun stopPlaySound() {
        mMediaPlayer?.stop()
        mMediaPlayer = null
    }
    ///////////////铃声

    ///////////////震动
    var vibrator: Vibrator? = null

    // todo 没了 activity 震动怎么办？
    fun startZD() {
        // vibrator = activity?.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
        val pattern = longArrayOf(500, 300, 500, 300) // 停止 开启 停止 开启
        vibrator?.vibrate(pattern, 2) //重复两次上面的pattern 如果只想震动一次，index设为-1
    }

    fun stopZD() {
        vibrator?.cancel()
    }
    ///////////////震动

    // todo 在 flutter 做监听后退 - done
    /*@Subscribe
    fun event(event: EventData.ClientHangUpEvent) {
        activity?.runOnUiThread {
            if (event.roomId == roomId) {
                showToast("业主已挂断")
                // todo 不知道能不能直接 finish, 可以直接用 flutter 的 onGoBack
                activity?.finish()
            }
        }
    }
    @Subscribe
    fun event(event: EventData.CallChangedEvent) {
        activity?.runOnUiThread {
            if (event.roomId == roomId) {
                showToast("超时未接听")
                // todo 不知道能不能直接 finish, 可以直接用 flutter 的 onGoBack
                activity?.finish()
            }
        }
    }*/

    // todo view 没有onDestroy，手动操作
    fun destroy() {
        stopPlaySound()
        stopZD()
    }
    /*override fun onDestroy() {
        super.onDestroy()
        EventBusUtils.unRegister(this)
        stopPlaySound()
        stopZD()
    }*/

    // todo - 直接隐藏返回键
    /*override fun onBackPressed() {
        //禁止返回，用户只能点击拒接才能返回上一个页面
    }*/
    
    
    // ---- 下面是原生中 BaseActivity 的方法
    
    private var dialog: DialogLoadingFragment? = null

    fun showDialogProgress(msg: String) {
        showDialogProgress(msg, false, null)
    }
    
    fun showDialogProgress(
            msg: String, cancelable: Boolean, onCancelListener: DialogInterface.OnCancelListener?
    ) {
        // todo 没有 supportFragmentManager 
        /*if (dialog == null) {
            dialog = DialogLoadingFragment.newInstance(msg)
            dialog?.show(supportFragmentManager)
        } else {
            if (!dialog!!.isResumed) {
                dialog?.show(supportFragmentManager)
            }
            dialog?.setMsg(msg)
        }*/
    }

    fun dismissDialog() {
        dialog?.dismiss()
    }
}
